<template>

    <ResourceTypeBtn @add-type="onAddType" @batch-remove="onBatchRemove"/>

    <Table border :columns="columns" :data="data" @on-selection-change="selection = $event" row-key="id"
         @on-select="checkNode" @on-select-cancel="uncheckNode" @on-expand-tree="expandTree"
         @on-select-all="selectionNodes(data, true)" @on-select-all-cancel="selectionNodes(data, false)">
        
        <template #status="{ row, index }">
            <DotTag type="primary" v-if="row.state">正常</DotTag>
            <DotTag type="error" v-else>失效</DotTag>
        </template>

        <template #action="{ row, index }">
            <Button type="success" v-auth:rtype:add:child icon="md-add-circle" size="small" style="margin-right: 5px" @click="addChildType(row)">添加子类型</Button>
            <Button type="primary" v-auth:rtype:modify icon="ios-create-outline" size="small" style="margin-right: 5px" @click="editType(row)">修改</Button>
            <Button type="error" v-auth:rtype:remove icon="ios-remove-circle-outline" size="small" @click="remove(row, index)">移除</Button>
        </template>

    </Table>

    <ResourceTypeForm v-model="drawer.state" v-if="drawer.state"
                      :title="drawer.title" :row="drawer.row"  @refresh-type="queryResourceTypes" />
</template>

<script setup>
import {ref,  reactive, onMounted, computed} from 'vue'
import Tips from '../message'
import DotTag from '../components/DotTag.vue';
import ResourceTypeBtn from '../components/resource/ResourceTypeBtn.vue'
import ResourceTypeForm from '../components/resource/ResourceTypeForm.vue'
import RSS from "../api/rssIndex.js";

const selection = ref([]) ; // 存储选中的多个节点， 通过 on-selection-change 事件进行赋值

// 控制表单的对象
const drawer = ref({
    state: false, 
    title: "" , 
    row: {}
});

const columns = reactive([
    {type: "selection",  width: 60, align: "center"}, 
    {title: "类型名" , key: "name", tree: true} ,
    {title: "状态" , slot: "status"} , 
    {title: "操作", slot: "action",  width: 280, align: "right"}
])

// 全部的资源类型数据
const resourceTypes = ref([]) ;

// 数据中必须有 id 和 pid (后面很多JS在处理节点效果中需要使用)
const data = computed(()=> convertResourceTypeStruct(resourceTypes.value, null)) ;
// 进入页面查询所有类型
onMounted(queryResourceTypes) ;

// 查询所有类型
function queryResourceTypes() {
  RSS.queryResourceTypeList().then(ret=> {
      if (ret.status) {
        resourceTypes.value = ret.list ;
      }
  })
}

/**
 * 转换资源类型结构
 */
function convertResourceTypeStruct(list, pid) {
  // 获取一级子节点
  let oneTypes = list.filter(type => type.pid == pid) ;
  // 递归 获取
  return oneTypes.map(type => {
      let children = convertResourceTypeStruct(list, type.id) ;
      return {
         id: type.id , name: type.name , state: type.state, _showChildren: false, pid: type.pid , children
      }
  })
}

function onAddType() { // 添加 资源类型
    drawer.value.state = true ;
    drawer.value.title = "添加资源类型" ;
    drawer.value.row = {name: "",  state: true} ;
}

function addChildType(row) { // 添加 二级资源类型
    drawer.value.state = true ;
    drawer.value.title = "添加二级资源类型" ;
    drawer.value.row = {pid: row.id, parentName: row.name, name: "", state: true} ;
}

function editType(row) {  // 修改类型
    drawer.value.state = true ;
    drawer.value.title = "修改资源类型" ;
    let pnode = findNodeFromDataById(data.value, row.pid);
    drawer.value.row = {...row, parentName: (pnode !=null ? pnode.name : '')} ;
}

function remove(row, index) { // 删除
    Tips.confirm("您确定要删除该分类吗，当前分类下的子分类也将会被删除？").then(()=> {
        RSS.removeResourceType(row.id).then(ret=> {
           if (ret.status) {
             Tips.success("删除成功");
             // 从资源类型中移除
             let index = resourceTypes.value.findIndex(type => type.id == row.id) ;
             resourceTypes.value.splice(index, 1) ;
           }
        })
    })
}

function onBatchRemove() { // 批量删除
    if (selection.value == null || selection.value.length ==0) {
        Tips.warning("请至少选择一个需要删除的资源分类"); return ;
    }
    Tips.confirm("您确定要删除选中的所有数据吗?").then(()=> {
        RSS.batchRemoveResourceType(selection.value.map(type => type.id)).then(ret=> {
           if (ret.status) {
             Tips.success("删除成功");
             queryResourceTypes();
           }
        })
    })
}

// 从 list 中查找 指定ID 对应的节点
function findNodeFromDataById(list, id) {
    // 根据 id 查找对应的节点数据
    let node = list.find(node => node.id === id) ; 
    // 如果没有找到，则遍历 data 
    if (node !=null) return node ;

    for(let i = 0 ; i < list.length; i++) {
        let n = list[i] ;
        if (n.children != null) {
            // 从孩子中查找节点 
            node = findNodeFromDataById(n.children, id); 
            if (node !=null) break ; // 退出循环，不在查找
        }
    }
    return node ;
}

// 展开或者收缩节点，将 _showChildren 的状态进行切换，为 勾选子节点服务
function expandTree(rowKey, status) {
    // 找到 对应的节点，并设置展开状态 
    let node = findNodeFromDataById(data.value, rowKey) ;
    if (node !=null) node._showChildren = status ;
}

// 将指定的节点及其子节点勾选状态 进行处理
function selectionNodes(nodes, status) {
    for(let i = 0 ; i < nodes.length ; i++) {
        let node = nodes[i] ; 
        node._checked = status ;
        if (node.children != null) {
            selectionNodes(node.children, status);
        }
    }
}

// 处理 父节点勾选状态
function selectParentNodes(pid, status) {
    let node = findNodeFromDataById(data.value, pid) ;
    if (node != null) {
        node._checked = status ; 
        if (node.pid != null && node.pid != '') selectParentNodes(node.pid, status);
    }
}

function checkNode(selection, row) { // selection : 选中的所有项， row 当前选中的行
    nodeStateChange(selection, row, true);
}

function uncheckNode(selection, row) {  // selection : 选中的所有项， row 当前取消的行
    nodeStateChange(selection, row, false);
}

function nodeStateChange(selection, row, status) {
    let node = findNodeFromDataById(data.value , row.id);
    if (node !=null) node._checked = status ; 
    // 判断是否是勾选，如果是，则 勾选父节点，将子节点也全部进行勾选
    if (status) {
        selectionNodes(node.children, true); // 选中所有的子元素
    }else{
        // 取消所有的父元素
        selectParentNodes(node.pid, false);
    }
}


</script>